function CountedCollection(){
	var theCollection = {};
	this.getIdentifiers = function(){
		var theResult = [];
		for(var theKey in counts){
			theResult.push(JSON.parse(theKey));
		}
		return theResult;
	};
	this.add = function(theIdentifier,theCount){
		if(theCount==null){
			this.add(theIdentifier,1);
			return;
		}else{
			this.setCount(theIdentifier,this.getCount(theIdentifier)+theCount);
		}
	};
	this.has = function(theIdentifier){
		return this.getCount(theIdentifier)>0;
	};
	this.remove = function(theIdentifier, theCount){
		if(theCount==null){
			this.remove(theIdentifier,1);
		}else{
			this.setCount(theIdentifier,this.getCount(theIdentifier)-theCount);
		}
	};

	this.getCount = function(theIdentifier){
		var theKey = JSON.stringify(theIdentifier);
		var theCount = theCollection[theKey];
		if(theCount==null) return 0;
		return theCount;
	};
	this.setCount = function(theIdentifier, theCount){
		var theKey = JSON.stringify(theIdentifier);
		if(theCount>0){
			theCollection[theKey] = theCount;
		}else{
			delete theCollection[theKey];
		}
	};
	
	var defaultComparisonFunction = function (first,second){
		if(first==second) return 0;
		if(first<second) return -1;
		return 1;
	};
	this.getMinimalValue = function(theComparisonFunction){
		if(theComparisonFunction==null) theComparisonFunction = defaultComparisonFunction;
		var theResult = null;
		for(var key in theCollection){
			if(theResult==null || theComparisonFunction(key,theResult)==-1){
				theResult = key;
			}
		}
		return JSON.parse(theResult);
	};
	this.getMaximalValue = function(theComparisonFunction){
		if(theComparisonFunction==null) theComparisonFunction = defaultComparisonFunction;
		var theResult = null;
		for(var key in theCollection){
			if(theResult==null || theComparisonFunction(key,theResult)==1){
				theResult = key;
			}
		}
		return JSON.parse(theResult);
	};
}
